package com.hb.trade.api.routine.controller.project.section;

import cfca.sadk.algorithm.common.PKIException;
import cfca.sadk.util.EncryptUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.json.JSONObject;
import com.hb.core.pojo.Attachment;
import com.hb.core.pojo.Attachments;
import com.hb.core.pojo.center.au.dto.ZappUserDTO;
import com.hb.core.pojo.center.sys.entity.FileRecord;
import com.hb.core.pojo.enums.FeeTypeEnum;
import com.hb.core.pojo.enums.PayStatusEnum;
import com.hb.core.pojo.project.file.dto.BidFileInfoDTO;
import com.hb.core.pojo.project.order.dto.UserOrderGoodsDTO;
import com.hb.core.pojo.project.order.entity.UserOrder;
import com.hb.core.pojo.project.section.dto.BidSectionDTO;
import com.hb.core.pojo.project.section.dto.BidSectionTenderDTO;
import com.hb.core.pojo.project.section.entity.BidSectionTender;
import com.hb.core.pojo.project.section.vo.ProjectInfoForMakeTenderFileVO;
import com.hb.trade.api.routine.service.tenderdoc.AbstractTenderDocumentOption;
import com.hb.trade.api.routine.service.tenderdoc.ScanQrTenderDocumentOption;
import com.hb.trade.api.routine.util.CommonUtil;
import com.hb.trade.api.routine.util.TenderFileCreateXmlUtil;
import com.hb.trade.client.center.FileClient;
import com.hb.trade.client.center.OrgClient;
import com.hb.trade.client.center.UserClient;
import com.hb.trade.client.project.BidFileInfoClient;
import com.hb.trade.client.project.SectionClient;
import com.hb.trade.client.project.TenderSectionClient;
import com.hb.trade.client.project.UserOrderClient;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.fzzn.core.auth.shiro.util.ShiroUtil;
import org.fzzn.core.file.entity.HbFileInfo;
import org.fzzn.core.file.entity.UploadEntity;
import org.fzzn.core.file.service.PersistenceService;
import org.fzzn.core.model.constant.CommonConstant;
import org.fzzn.core.model.enums.AuditStatusEnum;
import org.fzzn.core.model.enums.MsgEnum;
import org.fzzn.core.model.msg.Message;
import org.fzzn.core.model.msg.ResponseDto;
import org.fzzn.core.model.user.login.LoginUser;
import org.fzzn.core.model.user.login.SimpleUserExample;
import org.fzzn.core.service.ZipFileService;
import org.fzzn.core.util.IdUtil;
import org.fzzn.core.util.MsgUtil;
import org.fzzn.core.util.ResultUtil;
import org.fzzn.core.web.anno.Version;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;

/**
 * describe:
 * 投标人开标大厅操作
 *
 * @author zhaojk
 * @date 2021/12/03
 */
@Slf4j
@Version(1.0)
@Api(tags = {"投标人标段操作"})
@RequestMapping("/{version}")
@RestController
public class ApiSectionTenderController {

    protected final UserClient userClient;
    protected final UserOrderClient userOrderClient;
    protected final SectionClient sectionClient;
    protected final TenderSectionClient tenderSectionClient;
    protected final PersistenceService persistenceService;
    protected final OrgClient orgClient;
    protected final BidFileInfoClient bidFileInfoClient;

    public ApiSectionTenderController(UserClient userClient,
                                      UserOrderClient userOrderClient,
                                      SectionClient sectionClient,
                                      TenderSectionClient tenderSectionClient,
                                      PersistenceService persistenceService,
                                      OrgClient orgClient,
                                      BidFileInfoClient bidFileInfoClient) {
        this.userClient = userClient;
        this.userOrderClient = userOrderClient;
        this.sectionClient = sectionClient;
        this.tenderSectionClient = tenderSectionClient;
        this.persistenceService = persistenceService;
        this.orgClient = orgClient;
        this.bidFileInfoClient = bidFileInfoClient;
    }

    @ApiOperation(value = "保存投标信息", httpMethod = "POST")
    @PostMapping("/bidSectionTender/save")
    public ResponseDto save(@RequestBody BidSectionTenderDTO bidSectionTenderDto, HttpServletRequest request) {
        LoginUser<Long> loginUser = ShiroUtil.getUser();
        if (null == loginUser) {
            return ResultUtil.fail(MsgEnum.LOGIN_EXPIRE);
        }
        bidSectionTenderDto.buildBaseData(1);
        bidSectionTenderDto.setBidderId(loginUser.getId());
        bidSectionTenderDto.setIpAddress(CommonUtil.getClientIpAddress(request));
        ShiroUtil.fillOwner(bidSectionTenderDto);
        return ResultUtil.msg(sectionClient.save(bidSectionTenderDto));
    }

    @ApiOperation(value = "递交投标信息", httpMethod = "POST")
    @PostMapping("/bidSectionTender/submit")
    public ResponseDto submit(@RequestBody BidSectionTenderDTO bidSectionTenderDto, HttpServletRequest request) {
        Attachments tenderDocument = bidSectionTenderDto.getTenderDocument();
        if (CollUtil.isEmpty(tenderDocument)) {
            return ResultUtil.fail("请先上传投标文件");
        }

        // 投标文件操作类
        AbstractTenderDocumentOption option = new ScanQrTenderDocumentOption(tenderDocument);
        try {
            option.validate();
        } catch (Exception e) {
            return ResultUtil.fail(e.getMessage());
        }
        Long sectionId = option.getSectionId();
        // 对比标段ID
        if (NumberUtil.compare(sectionId, bidSectionTenderDto.getSectionId()) != 0) {
            return ResultUtil.fail("请上传对应标段的投标文件");
        }

        bidSectionTenderDto.buildBaseData(1);
        bidSectionTenderDto.setBidderId(ShiroUtil.getUserId());
        bidSectionTenderDto.setIpAddress(CommonUtil.getClientIpAddress(request));
        ShiroUtil.fillOwner(bidSectionTenderDto);
        Message<Boolean> submit = sectionClient.submit(bidSectionTenderDto);
        if (submit.getCode() == 200) {
            // 投标人递交成功后将投标人信息同步至供应商库
            BidSectionDTO bidSection = new BidSectionDTO();
            bidSection.setSectionId(bidSectionTenderDto.getSectionId());
            Message<BidSectionDTO> bidSectionProjectInfo = sectionClient.getBidSectionProjectInfo(bidSection);
            if (bidSectionProjectInfo.isSuccess() && null != bidSectionProjectInfo.getData()) {
                orgClient.tenderSaveSupply(bidSectionProjectInfo.getData().getOrgId(), ShiroUtil.getOrgId());
            }

        }
        return ResultUtil.msg(submit);
    }

    @ApiOperation(value = "在线递交投标信息", httpMethod = "POST")
    @PostMapping("/bidSectionTender/submitOnline")
    public ResponseDto submit(@RequestBody BidSectionTenderDTO bidSectionTenderDTO) {
        if (bidSectionTenderDTO.getSectionId() == null || bidSectionTenderDTO.getId() == null) {
            return ResultUtil.fail(MsgEnum.INCORRECT_PARAM);
        }

        Message<Boolean> message = sectionClient.submitOnline(bidSectionTenderDTO);
        if (message.isSuccess()) {
            // 保存到供应商库
            BidSectionDTO bidSectionDTO = new BidSectionDTO();
            bidSectionDTO.setSectionId(bidSectionTenderDTO.getSectionId());
            Message<BidSectionDTO> bidSectionProjectInfo = sectionClient.getBidSectionProjectInfo(bidSectionDTO);
            if (bidSectionProjectInfo.isSuccess() && null != bidSectionProjectInfo.getData()) {
                Message<Boolean> result = orgClient.tenderSaveSupply(bidSectionProjectInfo.getData().getOrgId(), ShiroUtil.getOrgId());
                return ResultUtil.msg(result);
            }
        }

        return ResultUtil.fail("递交失败");
    }


    @ApiOperation(value = "撤回投标信息", httpMethod = "POST")
    @PostMapping("/bidSectionTender/withdraw")
    public ResponseDto withdraw(@RequestBody BidSectionTenderDTO bidSectionTenderDto) {
        return ResultUtil.msg(sectionClient.withdraw(bidSectionTenderDto));
    }

    @ApiOperation(value = "根据标段Id统计投标总数、已递交、未递交数量", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "sectionId", value = "标段Id", dataTypeClass = Long.class)
    })
    @PostMapping("/bidSectionTender/countTender")
    public ResponseDto countTender(@RequestBody BidSectionTenderDTO bidSectionTenderDto) {
        Message<JSONObject> message = sectionClient.countTender(bidSectionTenderDto.getSectionId());
        return ResultUtil.msg(message);
    }

    @ApiOperation(value = "投标信息列表", httpMethod = "POST")
    @PostMapping("/bidSectionTender/list")
    public ResponseDto list(@RequestBody BidSectionTenderDTO bidSectionTender) {
        return ResultUtil.msg(sectionClient.list(bidSectionTender));
    }

    @ApiOperation(value = "根据主键Id查询投标详情", notes = "根据主键Id查询投标详情", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "主键Id", dataTypeClass = Long.class),
    })
    @PostMapping("/bidSectionTender/getDetailById")
    public ResponseDto getDetailById(@RequestBody BidSectionTenderDTO bidSectionTenderDTO) {
        return ResultUtil.msg(sectionClient.getDetailById(bidSectionTenderDTO));
    }

    @ApiOperation(value = "投标人查看投标信息详情", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "sectionId", value = "标段ID", required = true, dataTypeClass = String.class)
    })
    @PostMapping("/bidSectionTender/detail")
    public ResponseDto detail(@RequestBody BidSectionDTO bidSection) {
        Long sectionId = bidSection.getSectionId();

        Message<BidSectionTenderDTO> detailMsg = sectionClient.detail(sectionId, ShiroUtil.getUserId());
        BidSectionTenderDTO data = detailMsg.getData();

        UserOrderGoodsDTO userOrderGoodsDTO = new UserOrderGoodsDTO();
        userOrderGoodsDTO.setSectionId(sectionId);
        userOrderGoodsDTO.setOrgId(ShiroUtil.getOrgId());
        userOrderGoodsDTO.setFeeType(FeeTypeEnum.SYS_USE.getCode());
        userOrderGoodsDTO.addOrderStatus(PayStatusEnum.PAY_SUCCESS); // 查询支付成功的订单

        // 查询系统使用费的订单状态
        Message<UserOrder> msg = userOrderClient.queryUserOrder(userOrderGoodsDTO);
        if (msg.getData() != null) {
            data.setAuditStatus(msg.getData().getAuditStatus());
        }

        // 查询具体的费用值, 如果为0, 直接返回一个审核通过状态
        Message<BigDecimal> price = userOrderClient.getPrice(sectionId, FeeTypeEnum.SYS_USE.getCode());
        if (NumberUtil.equals(BigDecimal.ZERO, price.getData())) {
            data.setAuditStatus(AuditStatusEnum.PASSED.getCode());
        }

        return ResultUtil.msg(true, data);
    }

    /**
     * 获取当前用户作为投标人角色的数字信封
     * 必须为已经提交过投标文件
     * 若没有递交过则返回空
     * 当前登录用户必须拥有投标人角色
     *
     * @param bidSection
     * @return
     */
    @ApiOperation(value = "获取当前用户(投标人角色)的投标文件数字信封(未解密的)", notes = "获取当前用户(投标人角色)的投标文件数字信封(未解密的)")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "sectionId", value = "标段ID", dataTypeClass = Long.class),
    })
    @PostMapping("/bidSectionTender/digitalEnvelope")
    public ResponseDto digitalEnvelope(@RequestBody BidSectionTender bidSection) throws Exception {
        Long sectionId = bidSection.getSectionId();
        if (sectionId == null) {
            return ResultUtil.msg(MsgEnum.INCORRECT_PARAM);
        }

        Long userId = ShiroUtil.getUserId();
        Message<Attachment> detail = tenderSectionClient.tenderDocument(sectionId, userId);
        if (detail.isSuccess()) {
            // 投标文件一定只有一个
            Attachment attachment = detail.getData();

            AbstractTenderDocumentOption option = new ScanQrTenderDocumentOption(attachment);

            // 先验证投标文件
            option.validate();

            // 获取数字信封的信息
            JSONObject digitalEnvelopeJSON = option.getDigitalEnvelopeJSON();

            Message<ZappUserDTO> currentUser = userClient.getZappInfo(userId);
            if (currentUser.isFail()) {
                return ResultUtil.fail("未能获取用户的中招注册信息");
            }
            ZappUserDTO user = currentUser.getData();

            digitalEnvelopeJSON.putOpt("accessToken", user.getAccessToken());
            digitalEnvelopeJSON.putOpt("personalTransactionCode", user.getPersonalTransactionCode());
            digitalEnvelopeJSON.putOpt("unifiedTransactionCode", user.getUnifiedTransactionCode());

            return ResultUtil.msg(true, digitalEnvelopeJSON);

        }
        return ResultUtil.msg(detail);
    }

    /**
     * 投标人解密投标文件
     *
     * @param sectionTender
     * @return
     * @Updata fengbin 增加保存投标文件PDF 并将PDF投标文件保存值sys_file_record系统文件信息记录表中
     */
    @ApiOperation(value = "投标人解密投标文件", notes = "投标人解密投标文件")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "sectionId", value = "标段ID", dataTypeClass = Long.class),
            @ApiImplicitParam(name = "encStr", value = "对称加密密钥", dataTypeClass = String.class)
    })
    @PostMapping("/bidSectionTender/decryptTenderDocument")
    public ResponseDto decryptTenderDocument(@RequestBody BidSectionTenderDTO sectionTender) throws IOException {
        Long sectionId = sectionTender.getSectionId();
        if (sectionId == null) {
            return ResultUtil.fail("标段ID不能为空");
        }
        String encStr = sectionTender.getEncStr();
        if (StrUtil.isEmpty(encStr)) {
            return ResultUtil.fail("加密密钥不能为空");
        }

        // 当前登录用户作为投标人ID
        Long tenderId = ShiroUtil.getUserId();

        Message<Attachment> document = tenderSectionClient.tenderDocument(sectionId, tenderId);

        // 加密的投标文件
        Attachment attachment = document.getData();

        AbstractTenderDocumentOption option = new ScanQrTenderDocumentOption(attachment);

        try {
            // 验证一下先
            option.validate();

            // 解密操作
            option.decryptBase64(encStr);
        } catch (Exception e) {
            e.printStackTrace();
            return ResultUtil.fail(e.getMessage());
        }

        // 保存解密后的投标文件(zip)
        UploadEntity entity = new UploadEntity(option.getDecFile());
        List<HbFileInfo> fileInfos = persistenceService.uploadServer(entity);
        sectionTender.setBidderId(tenderId);
        Attachments attachments = Attachments.getInstance(fileInfos);
        sectionTender.setDecTenderDocument(attachments);

        // 上传投标文件pdf
        if (CollUtil.isNotEmpty(fileInfos)) {
            // 投标文件一定只有一个
            HbFileInfo hbFileInfo = fileInfos.get(0);

            File file = new File(hbFileInfo.getFilePath());
            ZipFileService instance = null;
            try {
                instance = ZipFileService.getInstance(file);
                File itemFile = instance.getItemFile(AbstractTenderDocumentOption.TENDER_DOC_SIGNATURE);
                UploadEntity entityPdf = new UploadEntity(itemFile);
                List<HbFileInfo> hbFilePdfs = persistenceService.uploadServer(entityPdf);
                Attachments attachmentPdfs = Attachments.getInstance(hbFilePdfs);
                sectionTender.setTenderPdf(attachmentPdfs);
                FileClient bean = SpringUtil.getBean(FileClient.class);
                //将解密后的PDF投标文件文件保存至sys_file_record系统文件信息记录表中
                FileRecord fileRecord = BeanUtil.toBean(attachmentPdfs.get(0), FileRecord.class);
                fileRecord.setId(IdUtil.getId());
                fileRecord.setDataTable("trade_bid_section_tender");
                fileRecord.setCreateTime(LocalDateTime.now());
                bean.saveFile(fileRecord);
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
        tenderSectionClient.saveDecryptFile(sectionTender);

        return ResultUtil.msg(true, option.getOpeningSchedule());
    }


    @ApiOperation(value = "获取投标人解密成功的投标文件列表", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "sectionId", value = "标段ID", required = true, dataTypeClass = String.class)
    })
    @PostMapping("/bidSectionTender/listBidSectionTender")
    public ResponseDto listBidSectionTender(@RequestBody BidSectionTenderDTO bidSectionTenderDTO) {
        SimpleUserExample loginUser = ShiroUtil.getUser();
        if (null == loginUser) {
            return ResultUtil.fail(MsgEnum.LOGIN_EXPIRE);
        }
        if (bidSectionTenderDTO.getSectionId() == null) {
            return ResultUtil.fail("标段ID不能为空");
        }
        bidSectionTenderDTO.setDecryptFlag(1);
        bidSectionTenderDTO.setStatus(1);
        Message<List<BidSectionTenderDTO>> detailMsg = sectionClient.listBidSectionTender(bidSectionTenderDTO);
        return ResultUtil.msg(detailMsg);
    }

//    @ApiImplicitParams({
//            @ApiImplicitParam(name = "id", value = "主键Id", dataTypeClass = Long.class),
//    })
//    @PostMapping("/bidSectionTender/getDetailById")
//    public ResponseDto getDetailById(@RequestBody BidSectionTenderDTO bidSectionTenderDTO) {
//        Message<BidSectionTender> detail = sectionClient.getDetailById(bidSectionTenderDTO);
//        if (detail.isFail() || detail.getData() == null || CollUtil.isEmpty(detail.getData().getDecTenderDocument())){
//            return ResultUtil.fail("未解密成功");
//        }
//        Attachment attachment = detail.getData().getDecTenderDocument().get(0);
//        List<HbFileInfo> fileInfos = persistenceService.listByFileNames(CollUtil.list(false, attachment.getFileName()));
//        if (CollUtil.isEmpty(fileInfos)){
//            return ResultUtil.fail("未查询到文件");
//        }
//        HbFileInfo hbFileInfo = fileInfos.get(0);
//        File file = hbFileInfo.getFile();
//        return ResultUtil.msg();
//    }

    // region 投标文件在线制作
    @ApiOperation(value = "投标文件在线编制获取项目信息", httpMethod = "POST")
    @PostMapping("/bidSectionTender/projectInfoForMakeTenderFile")
    public ResponseDto<ProjectInfoForMakeTenderFileVO> projectInfoForMakeTenderFile(@RequestBody BidSectionDTO bidSectionDTO) {
        Message<BidSectionDTO> bidSectionDTOMessage = sectionClient.getBidSectionProjectInfo(bidSectionDTO);
        BidSectionDTO bidSection = bidSectionDTOMessage.getData();
        if (bidSection == null) {
            return ResultUtil.fail("未查询到标段信息");
        }

        Long bidFileId = bidSection.getFileId();
        if (bidFileId == null) {
            return ResultUtil.fail("标段未关联招标文件");
        }

        Message<BidFileInfoDTO> bidFileInfoMsg = bidFileInfoClient.getBidFileInfo(bidFileId);
        if (bidFileInfoMsg.isFail()) {
            return ResultUtil.fail("未查询到招标文件信息");
        }

        BidFileInfoDTO bidFileInfo = bidFileInfoMsg.getData();

        // 组装数据
        ProjectInfoForMakeTenderFileVO projectInfo = new ProjectInfoForMakeTenderFileVO();
        projectInfo.setProjectName(bidSection.getProjectName());
        projectInfo.setProjectCode(bidSection.getProjectCode());
        projectInfo.setSectionName(bidSection.getSectionName());
        projectInfo.setControlPrice(bidSection.getControlPrice());
        projectInfo.setBiddingDocumentSignaturePdf(bidFileInfo.getBiddingDocumentSignaturePdf());
        projectInfo.setDrawing(bidFileInfo.getDrawing());

        return ResultUtil.msg(MsgUtil.msg(projectInfo));
    }

    @ApiOperation(value = "获取投标文件信息，在线制作", httpMethod = "POST")
    @PostMapping("/bidSectionTender/sectionTenderDetail")
    public ResponseDto<BidSectionTenderDTO> sectionTenderDetail(@RequestBody BidSectionTenderDTO bidSectionTenderDTO) {
        if (bidSectionTenderDTO.getSectionId() == null) {
            return ResultUtil.fail("标段id不能为空");
        }
        Long orgId = ShiroUtil.getOrgId();
        if (orgId == null) {
            return ResultUtil.fail("未获取到企业id");
        }
        bidSectionTenderDTO.setOrgId(orgId);

        Message<BidSectionTenderDTO> detailMsg = sectionClient.sectionTenderDetail(bidSectionTenderDTO);
        return ResultUtil.msg(detailMsg);
    }

    @ApiOperation(value = "在线保存并加密投标文件", httpMethod = "POST")
    @PostMapping("/bidSectionTender/saveAndEncryptTenderFileOnline")
    public ResponseDto<BidSectionTender> saveAndEncryptTenderFileOnline(@RequestBody BidSectionTenderDTO bidSectionTenderDTO, HttpServletRequest request) throws PKIException, IOException {
        // 参数验证
        // 验证开标一览表是否填写
        if (StrUtil.isEmpty(bidSectionTenderDTO.getOpeningScheduleContent())) {
            return ResultUtil.fail("缺少开标一览表内容");
        }

        bidSectionTenderDTO.setIpAddress(CommonUtil.getClientIpAddress(request));

        // 验证已签章的pdf文件是否存在
        if (CollectionUtil.isEmpty(bidSectionTenderDTO.getTenderPdfSignature())
            || bidSectionTenderDTO.getTenderPdfSignature().get(0).getFileUrl() == null) {
            return ResultUtil.fail("缺少已签章的投标文件");
        }

        // 验证数字信封信息是否存在
        if (bidSectionTenderDTO.getSecretKey() == null || bidSectionTenderDTO.getDigitalEnvelope() == null) {
            return ResultUtil.fail("数字信封信息缺失");
        }

        bidSectionTenderDTO.setBidderId(ShiroUtil.getUserId());
        bidSectionTenderDTO.setOrgId(ShiroUtil.getOrgId());

        // 投标信息落库
        Message<BidSectionTender> bidSectionTenderMessage = tenderSectionClient.saveTenderFileInfo(bidSectionTenderDTO);
        if (bidSectionTenderMessage.isSuccess() && bidSectionTenderDTO.getId() == null) {
            bidSectionTenderDTO.setId(bidSectionTenderMessage.getData().getId());
        }

        String fileId = IdUtil.getIdStr();

        // 生成未加密的投标文件
        File tenderFile = zipTenderFile(fileId, bidSectionTenderDTO);
        if (tenderFile == null) {
            return ResultUtil.fail("生成投标文件报错");
        }

        // 加密投标文件
        File encryptTenderFile = encryptTenderFile(fileId, bidSectionTenderDTO.getSectionId().toString(), tenderFile, bidSectionTenderDTO.getSecretKey(), bidSectionTenderDTO.getDigitalEnvelope());

        // 上传oss
        UploadEntity tenderUploadEntity = new UploadEntity(tenderFile);
        List<HbFileInfo> tenderFileInfoList = persistenceService.uploadServer(tenderUploadEntity);
        if (tenderFileInfoList.size() == 0) {
            return ResultUtil.fail("投标文件上传OSS失败");
        }

        UploadEntity encryptTenderUploadEntity = new UploadEntity(encryptTenderFile);
        List<HbFileInfo> encryptTenderFileInfoList = persistenceService.uploadServer(encryptTenderUploadEntity);
        if (encryptTenderFileInfoList.size() == 0) {
            return ResultUtil.fail("加密后的投标文件上传OSS失败");
        }

        // 数据落库
        Attachments tenderAttachments = new Attachments();
        for (HbFileInfo fileInfo : tenderFileInfoList) {
            Attachment attachment = BeanUtil.copyProperties(fileInfo, Attachment.class);
            tenderAttachments.add(attachment);
        }
        bidSectionTenderDTO.setUnencryptedDocument(tenderAttachments);

        Attachments encryptTenderAttachments = new Attachments();
        for (HbFileInfo fileInfo : encryptTenderFileInfoList) {
            Attachment attachment = BeanUtil.copyProperties(fileInfo, Attachment.class);
            encryptTenderAttachments.add(attachment);
        }
        bidSectionTenderDTO.setTenderDocument(encryptTenderAttachments);

        Message<BidSectionTender> tenderMessage = tenderSectionClient.saveTenderFileInfo(bidSectionTenderDTO);

        return ResultUtil.msg(tenderMessage);
    }

    /**
     * 生产未加密投标文件
     *
     * @param bidSectionTenderDTO
     * @return
     */
    private File zipTenderFile(String fileId, BidSectionTenderDTO bidSectionTenderDTO) {
        BidSectionDTO bidSectionDTO = new BidSectionDTO();
        bidSectionDTO.setSectionId(bidSectionTenderDTO.getSectionId());
        Message<BidSectionDTO> bidSectionProjectMessage = sectionClient.getBidSectionProjectInfo(bidSectionDTO);
        BidSectionDTO sectionDTO = bidSectionProjectMessage.getData();
        if (sectionDTO == null) {
            return null;
        }
        if (sectionDTO.getFileId() == null) {
            return null;
        }

        Message<BidFileInfoDTO> bidFileInfoMessage = bidFileInfoClient.getBidFileInfo(sectionDTO.getFileId());
        BidFileInfoDTO bidFileInfoDTO = bidFileInfoMessage.getData();

        // 生成 zbInfoxml.xml
        File zbInfoXml = TenderFileCreateXmlUtil.createZbInfoXml(sectionDTO, bidFileInfoDTO, fileId);
        // 生成 fileKBYLxml.xml
        File openingSchedulerXml = TenderFileCreateXmlUtil.createKBYLBXml(bidSectionTenderDTO.getOpeningScheduleContent(), fileId);
        // 生成 fileGuidxml.xml
        File fileGuidXml = TenderFileCreateXmlUtil.createFileGuidXml(UUID.randomUUID().toString(), fileId);
        // 生成 tbinfo.xml
        File tbinfoXml = TenderFileCreateXmlUtil.createTbInfo(fileId);

        // 签章的招标文件
        File bidFile = bidFileInfoDTO.getBiddingDocumentSignaturePdf().get(0).getThisFile();
        // 签章的投标文件
        File tenderFile = bidSectionTenderDTO.getTenderPdfSignature().get(0).getThisFile();

        // 打包成zip文件
        ZipFileService zipFileService = ZipFileService.getInstance();
        zipFileService.add("zbInfoxml.xml", zbInfoXml);
        zipFileService.add("fileKBYLxml.xml", openingSchedulerXml);
        zipFileService.add("fileGuidxml.xml", fileGuidXml);
        zipFileService.add("tbinfo.xml", tbinfoXml);
        zipFileService.add("biddingSignature.pdf", bidFile);
        zipFileService.add("tenderDocSignature.pdf", tenderFile);

        String zipFileSuffix;
        // 工程、货物、服务、预审
        switch (sectionDTO.getProjectType()) {
            case "1":
                zipFileSuffix = "GC";
                break;
            case "2":
                zipFileSuffix = "HW";
                break;
            case "3":
                zipFileSuffix = "FW";
                break;
            default:
                zipFileSuffix = "YS";
                break;
        }
        String zipFilePath = fileId + "/" + sectionDTO.getProjectName() + sectionDTO.getSectionName() + "投标文件." + zipFileSuffix;
        File zipFile = zipFileService.file(zipFilePath);

        return zipFile;
    }

    /**
     * 机密投标文件
     *
     * @param tenderFile 未加密的投标文件
     * @param secretKey  秘钥
     * @return
     */
    private File encryptTenderFile(String fileId, String sectionId, File tenderFile, String secretKey, String digitalEnvelope) throws PKIException {
        File encryptFile = new File(CommonConstant.TEMP_PATH + "/" + fileId + "/" + "tbwj.enc");
        secretKey = Base64.decodeStr(secretKey);
        EncryptUtil.encryptFileByDES3(tenderFile.getAbsolutePath(), encryptFile.getAbsolutePath(), secretKey);

        // 生成 digitalEnvelopexml.xml
        File digitalEnvelopeXml = TenderFileCreateXmlUtil.createDigitalEnvelopeXml(sectionId, digitalEnvelope, fileId);

        // 打包成zip文件
        ZipFileService zipFileService = ZipFileService.getInstance();
        zipFileService.add("tbwj.enc", encryptFile);
        zipFileService.add("digitalEnvelopexml.xml", digitalEnvelopeXml);
        String tenderFileName = tenderFile.getName();
        String tenderFilePrefix = tenderFileName.substring(0, tenderFileName.lastIndexOf("."));
        String tenderFileSuffix = tenderFileName.substring(tenderFileName.lastIndexOf("."),tenderFileName.length());
        String zipFilePath = fileId + "/" + tenderFilePrefix + "(已加密)" + tenderFileSuffix;
        File zipFile = zipFileService.file(zipFilePath);

        return zipFile;
    }

    @ApiOperation(value = "获得数字信封明文", httpMethod = "POST")
    @GetMapping("/bidSectionTender/getSecretKey")
    public ResponseDto<String> getSecretKey() {
        String secretKey = UUID.randomUUID().toString().replace("-", "") + UUID.randomUUID().toString().replace("-", "");
        // 跟投标编制文件同步 返回的key是个base64
        secretKey = Base64.encode(secretKey);
        return ResultUtil.msg(MsgUtil.msg(secretKey));
    }

    // endregion

}
